from abc import ABC, abstractmethod
import requests
from .models import User, UserSocialAccount
from utils.jwttool import tooljwt

# 1. 抽象工厂类
class AbstractLoginFactory(ABC):
    @abstractmethod
    def get_auth_url(self):
        pass

    @abstractmethod
    def get_user_info(self, code):
        pass

    @abstractmethod
    def process_login(self, user_info):
        pass

# 2. 具体工厂类（以钉钉为例）
class DingTalkLoginFactory(AbstractLoginFactory):
    def get_auth_url(self):
        from urllib.parse import quote
        params = [
            f"redirect_uri={quote('http://127.0.0.1:5173/createuser')}",
            "response_type=code",
            "client_id=ding1vc9mavivqifn3kh",
            "scope=openid",
            "prompt=consent"
        ]
        url = "https://login.dingtalk.com/oauth2/auth?" + ("&".join(params))
        return url

    def get_user_info(self, code):
        # 获取accessToken
        data = {
            "clientId": "ding1vc9mavivqifn3kh",
            "clientSecret": "yhxvd0eLqgFpwyi2HLGmw6XlMl9pAwJj2gYo3PBVGhiGW_M45_iUag8pRfc3AwSy",
            "code": code,
            "grantType": "authorization_code"
        }
        resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        accessToken = resp.get('accessToken')
        headers = {"x-acs-dingtalk-access-token": accessToken}
        user_info = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        user_info['accessToken'] = accessToken
        return user_info

    def process_login(self, user_info):
        name = user_info.get('nick')
        uid = user_info.get('openId')
        phone = user_info.get('mobile')
        avatarUrl = user_info.get('avatarUrl')
        accessToken = user_info.get('accessToken')

        sfl = UserSocialAccount.objects.filter(openid=uid, platform="0").first()
        if not sfl:
            if not phone:
                return {"code": 400, "msg": "钉钉未返回手机号，无法注册/登录"}
            user = User.objects.filter(phone=phone).first()
            if not user:
                user = User.objects.create(phone=phone, real_name=name, avatar=avatarUrl)
            UserSocialAccount.objects.create(
                user=user,
                platform="0",
                openid=uid,
                token=accessToken
            )
            token = tooljwt.getjwt({"userid": user.id})
            rToken = tooljwt.getrjwt({"userid": user.id})
            return {"code": 202, 'token': token, "userid": user.id, "rtoken": rToken}
        else:
            user = sfl.user
            sfl.token = accessToken
            sfl.save()
            token = tooljwt.getjwt({"userid": user.id})
            rToken = tooljwt.getrjwt({"userid": user.id})
            return {"code": 200, 'token': token, "userid": user.id, "rtoken": rToken}

# 3. 客户端调用类
class LoginClient:
    def __init__(self, factory):
        self.factory = factory

    def get_auth_url(self):
        return self.factory.get_auth_url()

    def login(self, code):
        user_info = self.factory.get_user_info(code)
        return self.factory.process_login(user_info) 